//
// Created by zhfayuan on 2021/6/15.
//

#ifndef GB28181KIT_GBGWCHANNEL_H
#define GB28181KIT_GBGWCHANNEL_H


#include <string>
#include <memory>
#include <thread>
#include <mutex>
#include <deque>
#include <array>
#include <vector>
#include <condition_variable>
#include "GbtProxyKit.h"
#include "AacDecoder.h"
#include "AudioResampler.h"
#include "AacEncoder.h"

struct RawPacket
{
    bool key;
    bool hevc;
    uint64_t pts;
    uint32_t  type;
    std::vector<uint8_t> data;
};

class GBGwChannelHandler
{
public:
    virtual void onBeginPlay(uint32_t index)  = 0;
    virtual void onEndPlay(uint32_t index) = 0;
};

class GBGwChannel:public gbt::GbtMediaDeviceSink
{
public:
    GBGwChannel(GBGwChannelHandler* handle,std::string name,std::string parent,std::string dev,uint32_t index);
    virtual ~GBGwChannel();
private:
    gbt::GbtMediaDevice *_device;
private:
    volatile bool _online;
    GBGwChannelHandler *_live_handler;
    GBT_Catalog _gbtCatalog;
    uint32_t  _audio_sample_rate;
    uint32_t  _audio_channel;
    uint32_t   _index;

    uint64_t _last_v_ts;
    uint64_t _last_a_ts;
private:
    std::shared_ptr<AacDecoder> _aac_decoder;
    std::shared_ptr<AacEncoder> _aac_encoder;
    std::shared_ptr<AudioResampler> _audio_resampler;
private:
    volatile bool _pktAbort;
    volatile bool _pktRun;
 
    std::mutex _pktLock;
    std::condition_variable _pktCond;
    std::shared_ptr<std::thread> _pktThread;
    std::deque<std::shared_ptr<RawPacket>> _pktQue;
private:
    void pktThreadEntry();
protected:
    virtual void onEndPlay(gbt::GbtMediaDevice* device, const char* peerID);
    virtual void onBeginPlay(gbt::GbtMediaDevice* device, const char* peerID);
public:
    virtual void writeAudio(char *data, uint32_t length, uint64_t  pts);
    virtual void writeVideo(char *data, uint32_t length, uint64_t  pts,bool key,bool hecv);
public:
    virtual  void online();
    virtual  void offline();
    GBT_Catalog &getCatalog();
};

#endif //GB28181KIT_GBGWCHANNEL_H
